package com.SpringDataBaseBak.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.ZipUtil;
import com.SpringDataBaseBak.config.DataBaseBakConfig;
import com.SpringDataBaseBak.constants.MysqlConstant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author chenming
 * @description
 * @create: 2022-08-16
 */
@Component
@Slf4j
public class BakTask implements ApplicationRunner {

    @Autowired
    private DataBaseBakConfig dataBaseBakConfig;

    private static String sourcePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath();
    private static File file = new File(sourcePath);

    @Override
    public void run(ApplicationArguments args) throws Exception {
//        Timer timer = new Timer();
//        timer.schedule(new TimerTask() {
//            @SneakyThrows
//            @Override
//            public void run() {
//                String yyyymMdd = DateUtil.format(new Date(), dataBaseBakConfig.getDateFormat());
//                File bakFile = new File(dataBaseBakConfig.getFilePath() + File.separator + yyyymMdd);
//                if (!bakFile.exists()) {
//                    bakFile.mkdirs();
//                }
//
//                List<File> fileLs = FileUtil.loopFiles(dataBaseBakConfig.getFilePath());
//                for (File fileName : fileLs) {
//                    Date date = DateUtils.addMilliseconds(DateUtils.parseDate(FileUtil.getPrefix(fileName), dataBaseBakConfig.getDateFormat()), (int) dataBaseBakConfig.getMaxStorageDuration());
//                    if (date.before(new Date())) {
//                        FileUtil.del(fileName);
//                    }
//                }
//
//                String excludePrefix = dataBaseBakConfig.getExcludePrefix();
//                String includePrefix = dataBaseBakConfig.getIncludePrefix();
//                List<String> table = null;
//                boolean flag = false;
//                if (excludePrefix != null) {
//                    flag = true;
//                    table = getExcludeTable(excludePrefix);
//                }
//                if (includePrefix != null) {
//                    flag = true;
//                    table = getIncludeTable(includePrefix);
//                }
//
//                if (flag) {
//                    for (String tableName : table) {
//                        StringBuilder sb = new StringBuilder();
//                        String sqlName = bakFile.getAbsolutePath() + File.separator + tableName + ".sql";
//                        String cmd = sb.append(MysqlConstant.START_CMD).append(MysqlConstant.MYSQLDUMP)
//                                .append(" -h ").append(dataBaseBakConfig.getTargetHost())
//                                .append(" -u").append(dataBaseBakConfig.getTargetUsername())
//                                .append(" -p").append(dataBaseBakConfig.getTargetPassword())
//                                .append(" --compress=true ")
//                                .append(" --quick")
//                                .append(" --databases ").append(dataBaseBakConfig.getTargetSchema())
//                                .append(" --tables ").append(tableName)
//                                .append(" --result-file=").append(sqlName).toString();
//                        log.info(cmd);
//                        Process exec = RuntimeUtil.exec(null, file, cmd);
//                    }
//                } else {
//                    table = getExcludeTable("*");
//                    for (String tableName : table) {
//                        StringBuilder sb = new StringBuilder();
//                        String sqlName = bakFile.getAbsolutePath() + File.separator + tableName + ".sql";
//                        String cmd = sb.append(MysqlConstant.START_CMD).append(MysqlConstant.MYSQLDUMP)
//                                .append(" -h ").append(dataBaseBakConfig.getTargetHost())
//                                .append(" -u").append(dataBaseBakConfig.getTargetUsername())
//                                .append(" -p").append(dataBaseBakConfig.getTargetPassword())
//                                .append(" --compress=true ")
//                                .append(" --quick")
//                                .append(" --databases ").append(dataBaseBakConfig.getTargetSchema())
//                                .append(" --tables ").append(tableName)
//                                .append(" --result-file=").append(sqlName).toString();
//                        log.info(cmd);
//                        Process exec = RuntimeUtil.exec(null, file, cmd);
//                    }
//                }
//                Thread.sleep(dataBaseBakConfig.getDelay() - 10);
//                ZipUtil.zip(bakFile);
//                FileUtil.del(bakFile);
//            }
//        }, 0, dataBaseBakConfig.getDelay());
    }

    private List<String> getExcludeTable(String prefix) {
        StringBuilder sb = new StringBuilder();
        String cmd = sb.append(MysqlConstant.START_CMD)
                .append(MysqlConstant.MYSQL)
                .append(" -h ").append(dataBaseBakConfig.getTargetHost())
                .append(" -u").append(dataBaseBakConfig.getTargetUsername())
                .append(" -p").append(dataBaseBakConfig.getTargetPassword())
                .append(" -e ").append("\"SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE table_schema = '")
                .append(dataBaseBakConfig.getTargetSchema()).append("' AND table_name NOT LIKE concat('%', '").append(prefix).append("','%')\"").toString();
        Process exec = RuntimeUtil.exec(null, file, cmd);
        List<String> resultLines = RuntimeUtil.getResultLines(exec, StandardCharsets.UTF_8);
        resultLines.remove(0);
        return resultLines;
    }

    private List<String> getIncludeTable(String prefix) {
        StringBuilder sb = new StringBuilder();
        String cmd = sb.append(MysqlConstant.MYSQL)
                .append(" -h ").append(dataBaseBakConfig.getTargetHost())
                .append(" -u").append(dataBaseBakConfig.getTargetUsername())
                .append(" -p").append(dataBaseBakConfig.getTargetPassword())
                .append(" -e ").append("\"SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE table_schema = '")
                .append(dataBaseBakConfig.getTargetSchema()).append("' AND table_name LIKE concat('%', '").append(prefix).append("','%')\"").toString();
        Process exec = RuntimeUtil.exec(null, file, cmd);
        List<String> resultLines = RuntimeUtil.getResultLines(exec, StandardCharsets.UTF_8);
        resultLines.remove(0);
        return resultLines;
    }
}
